package mint.modules.generator;

import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

import mint.modules.symbol.Symbol;
import mint.modules.symbol.SymbolFactory;

import org.antlr.runtime.tree.Tree;

public class CompilationUnitNode extends Scope implements MintNode {
	private List<ClassDeclarationNode> classNodeList;
	
	public CompilationUnitNode(Tree compilationUnitTree)
	{
		super(null, null);
		classNodeList = new ArrayList<ClassDeclarationNode>();
		loadClasses(compilationUnitTree);
	}
	
	@Override
	public void printSymbolTable(Formatter output, int tabSize) {
		for (int i = 0; i < classNodeList.size(); i++)
		{
			ClassDeclarationNode node = classNodeList.get(i);
			Symbol symbol = searchSymbol(node.getName(), getContainerClass(), false);
			
			symbol.print(output, tabSize);
			node.printSymbolTable(output, tabSize + 1);
		}
	}

	@Override
	public void testSemantic() {
		for (int i = 0; i < classNodeList.size(); i++)
		{
			ClassDeclarationNode node = classNodeList.get(i);
						
			node.testSemantic();			
		}
	}

	@Override
	public List<String> getSemanticErrors() {
		List<String> errors = new ArrayList<String>();
		
		for (int i = 0; i < classNodeList.size(); i++)
		{
			ClassDeclarationNode node = classNodeList.get(i);
			
			errors.addAll(node.getSemanticErrors());
		}
			
		return errors;
	}

	@Override
	public void emit(Formatter output) {		
		for (int i = 0; i < classNodeList.size(); i++)
		{
			ClassDeclarationNode node = classNodeList.get(i);
			
			node.emit(output);			
		}
	}
	
	@Override
	public int getLine() {	
		return 0;
	}
	
	private void loadClasses(Tree compilationUnitTree)
	{
		Tree classTree;
		ClassDeclarationNode node;
		
		for (int i = 0; i < compilationUnitTree.getChildCount(); i++)
		{
			classTree = compilationUnitTree.getChild(i);			
			node = new ClassDeclarationNode(this, classTree);
			classNodeList.add(node);
			addSymbol(SymbolFactory.createClassSymbol(node));
		}
	}	
}
